#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sikle.h"

void Stdlib_malloc(SikleState* ss)
{
  SPointer pointer;
  SInteger integer;
  StacelType type;

  if(get_stacel_type(ss) == STACEL_INTEGER) {
    type = stacel_types[STACEL_INTEGER];
    type.operation->pop(ss, STACEL(&integer));

    pointer.type = STACEL_POINTER;
    pointer.value = malloc(integer.value);
    
    if(pointer.value == NULL) {
      log_msg(LOG_FATAL, "memory alloc failed.", NULL);
    }

    type = stacel_types[STACEL_POINTER];
    type.operation->push(ss, STACEL(&pointer));
  }
  else {
    log_msg(LOG_ERROR, "_builtin_malloc error", NULL);
  }
}

void Stdlib_free(SikleState* ss)
{
  SPointer pointer;
  StacelType type;

  if(get_stacel_type(ss) == STACEL_POINTER) {
    type = stacel_types[STACEL_POINTER];
    type.operation->pop(ss, STACEL(&pointer));

    if(pointer.value == NULL) {
      return ;
    }

    free(pointer.value);
  }
  else {
    log_msg(LOG_ERROR, "_builtin_free error", NULL);
  }
}

void Stdio_register_words(SikleState* ss)
{
  register_builtin_word(ss, "malloc", Stdlib_malloc);
  register_builtin_word(ss, "free", Stdlib_free);
}

void dummy_init(SikleState* ss)
{

}

void dummy_destory(SikleState* ss)
{

}

SikleLibOperation stdlib_ops = {
  .library_init = dummy_init,
  .register_library_words = Stdio_register_words,
  .library_destory = dummy_destory
};
